package com.yelaoshi.controller;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.CircleCaptcha;
import cn.hutool.captcha.GifCaptcha;
import com.yelaoshi.common.Result;
import com.yelaoshi.domain.SysUser;
import com.yelaoshi.dto.SysUserDto;
import com.yelaoshi.service.UserService;
import com.yelaoshi.vo.PageInfo;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * 用户的控制器
 */
@RestController
@RequestMapping("/sysuser")
public class SysUserController {

    @Autowired
    private UserService userService;

    /**
     * 用户登录
     *
     * @param username 用户名称
     * @param password 密码
     */
    @PostMapping("/login.do")
    public Result doLogin(String username, String password, String code) {
        // 0 校验验证码
        validateCode(code);
        // 1 创建token
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        // 2 获取主体
        Subject subject = SecurityUtils.getSubject();
        // 3 执行登录===>UserRealm.doGetAuthenticationInfo
        subject.login(token);
        // 4 没有抛异常就是登录成功
        System.out.println("登录成功");
        return Result.ok();
    }

    /**
     * 用户的登出
     *
     * @return
     */
    @GetMapping("/logout.do")
    public Result logout() {
        // shiro 实现登录
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return Result.ok();
    }

    @GetMapping("/codeImg.do")
    public void createCodeImg(HttpServletResponse response, HttpSession session) throws IOException {
        // 1 产生一个验证码 130 × 48
        CircleCaptcha circleCaptcha = CaptchaUtil.createCircleCaptcha(130, 48, 1, 0);
        // 2 保持验证码
        session.setAttribute("CODE_IMG", circleCaptcha.getCode());
        // 3 将验证码写出去
        circleCaptcha.write(response.getOutputStream());
    }


    /**
     * 校验验证码
     *
     * @param code 用户输入的验证码
     */
    private void validateCode(String code) {
        // 1 获取session 里面的验证码
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpSession session = requestAttributes.getRequest().getSession();
        Object codeImg = session.getAttribute("CODE_IMG");
        if (codeImg == null) {
            throw new IllegalArgumentException("请获取验证码后重试!");
        }
        // 2 对比2 个验证码
        if (!codeImg.toString().equalsIgnoreCase(code)) {
            throw new IllegalArgumentException("验证码输入错误");
        }

    }

    //////////////////////////////////////////////用户的增删改查///////////////////////////////////////////
    /**
     *   接收前端的参数,我们以后使用DTO 对象来接收
     *   Data Transport Object
     *   接收前端的参数传递给Service
     *  我们给前端响应数据时,我们响应数据名称为: Vo
     *  View Object
     *
     *  domain = > 模型类 == > POJO 对象
     *
     *  (前端->后端) (后端==>数据库) (后端==>前端)
     *  DTO = >     POJO = >       VO
     *
     */

    /**
     * 新增用户
     * tip: 怎么接收前端的参数进来
     * 前端是json 数据, 因为前端添加了 contentType:'application/json',
     * @return
     */
    @PostMapping("/add.do")
    public Result addUser(@RequestBody SysUserDto dto) {
        boolean isOk = userService.addUser(dto);
        return isOk ? Result.ok() : Result.fail();
    }

    /**
     * 删除用户 支持 单个删除 支持批量的删除
     * tip: 使用id 删除用户
     *
     * @return
     */
    @PostMapping("/delete.do/{ids}")
    public Result deleteUser(@PathVariable("ids") Integer []ids) {
       Boolean isDelete =  userService.batchDelete(ids) ;
        return isDelete ? Result.ok() : Result.fail();
    }

    /**
     * 修改用户给
     * tip: 怎么接收参数进来
     *
     * @return
     */
    @PostMapping("/update.do")
    public Result updateUser(SysUserDto dto) {
        Boolean isOk = userService.updateUser(dto);
        return isOk ? Result.ok() : Result.fail();
    }

    /**
     * 分页查询用户
     * 给前端的数据怎么封装 --- 前端需要做匹配吗?
     *
     * @return
     */
    @GetMapping("/findByPage.do")
    public Result findByPage(SysUserDto dto) {
        PageInfo<SysUser> pageData = userService.findByPage(dto);
        return Result.ok(pageData);
    }
}
